<template>
  <Select v-model:value="server" :options="options" style="width: 240px; position: absolute; top: 2px; right: 10px"></Select>
  <div class="resources">
    <div v-for="res of resources" :class="res.class">
      <h2>{{ res.title }}</h2>
      <div :id="res.id" class="shell">
        <p v-for="d of res.datas" v-html="replaceWhitespace(d)"></p>
      </div>
    </div>
  </div>
</template>
<script setup>
  import { useStore } from 'vuex';
  import { ref, inject, watch, onMounted, nextTick } from 'vue';
  import { Select } from 'ant-design-vue';

  import { replaceWhitespace } from '@/libs/helpers';

  const commands = {
    free: { title: '内存使用率', class: 'col-7', command: 'free -h;' },
    netstat: { title: '网络使用', class: 'col-3', command: `netstat -an | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}';` },
    df: { title: '磁盘分区使用率', class: 'full', command: 'df -h;' }
  };

  const props = defineProps({
    maxHeight: String | Number
  });

  const $store = useStore();
  const $http = inject('$http');
  const $eventBus = inject('$eventBus');

  const server = ref('');
  const options = ref([]);

  const resources = ref([]);

  async function getResources(cmd, key) {
    let command = {
      command: `${server.value} ${cmd.command}`
    };

    let res = await $http.post('/api/shell/exec', command);

    return { id: key, title: cmd.title, datas: res.datas, class: cmd.class };
  }

  async function getConfigs() {
    options.value.length = 0;

    let res = await $http.get('/api/trac/configs');

    options.value = (res.datas || []).map(d => {
      return { label: d.Description, value: d.Value };
    });
  }

  async function monitors() {
    let promise = [];

    for (let key in commands) {
      commands[key].datas = [];

      promise.push(getResources(commands[key], key));
    }

    await Promise.all(promise).then(values => {
      resources.value = values;
    });
  }

  function resizeDfContainer(client) {
    let df = document.getElementById('df');

    if (df) {
      df.style.marginBottom = 0;
      df.style.height = client.height - 268 + 'px';
    }
  }

  watch(server, () => monitors());

  onMounted(async () => {
    await getConfigs();

    await monitors();

    $eventBus.on('windowResizeChanged', client => resizeDfContainer(client));

    nextTick(() => resizeDfContainer($store.state.area.content));
  });
</script>

<style lang="less" scoped>
  .resources {
    width: 100%;
    display: flex;
    flex-flow: row wrap;
    align-items: top;
    justify-content: space-between;

    > div {
      border-radius: 5px;
      padding: 0;
      border: 1px solid #245580;
      flex: 0 0 49%;
      overflow: auto;
      width: 100%;
      display: inline-block;
      margin-bottom: 5px;

      > h2 {
        margin: 0;
        padding: 8px 10px;
        color: #fff;
        font-size: 18px;
        position: relative;
        vertical-align: top;
        font-weight: bolder;
        user-select: none;
        background-image: linear-gradient(to bottom,#337ab7 0,#265a88 100%);
      }

      > .shell {
        width: 100%;
        display: inline-block;
        overflow: auto;
        height: 300px;
      }

      &.full {
        flex: 0 0 100%;

        > .shell {
          height: 305px;
        }
      }

      &.col-7,
      &.col-3 {
        > .shell {
          height: 100px;
        }
      }

      &.col-7 {
        flex: 0 0 69.5%;
      }

      &.col-3 {
        flex: 0 0 29.5%;
      }
    }
  }
</style>
